#include "exc_screen.h"
#include <QQuickWidget>
#include <QQmlContext>
#include <QLocalSocket>
#include <QMessageBox>
#include <QLabel>
#include <QtConcurrent>

#include <iostream>
ExcScreen::ExcScreen()
{
    //1-qml interface
    sql_mcDefine = new Sql_MCDefine();
    sql_mcRecorder = new Sql_MCRecorder(sql_mcDefine);
    m_excQmlModbusInterface = new ExcQmlModbusInterface(sql_mcRecorder);

    //2-qml ui
    m_quickWidget=new QQuickWidget();
    //2.2-register property to qml, to let qml use c++ member
    m_quickWidget->rootContext()->setContextProperty("$sqlMcDefine", sql_mcDefine);
    m_quickWidget->rootContext()->setContextProperty("$sqlMcRecorder", sql_mcRecorder);
    m_quickWidget->rootContext()->setContextProperty("$modbusInterface", m_excQmlModbusInterface);
    m_quickWidget->rootContext()->setContextProperty("$operatorMode", sql_mcRecorder->m_operatorMode);
    connect(m_excQmlModbusInterface, &ExcQmlModbusInterface::SN_close, this, [this](){m_quickWidget->close();});

    QUrl source("qrc:/qml/Screen_QML_Main.qml");
    m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    m_quickWidget->setSource(source);
    m_quickWidget->showFullScreen();
    m_quickWidget->setWindowTitle("EXC SCREEN V3.1.6_C2.27_U20");
    m_quickWidget->show();

    //3-localSocket connect error
    if(!sql_mcDefine->IsOpenSuccess() || !sql_mcRecorder->IsOpenSuccess())
    {
        connect(this, &ExcScreen::SN_connectToLocalSocketFault,
                this, [this](){
            QDialog *t_dialog = new QDialog();
            t_dialog->show();
            QString t_str;
            if(!sql_mcDefine->IsOpenSuccess())
                t_str = t_str + "\r\nsql EXC_MC_DEFINE open fail";
            if(!sql_mcRecorder->IsOpenSuccess())
                t_str = t_str + "\r\nsql EXC_MC_RECORDER open fail";
            QMessageBox::information(t_dialog, tr("source requiru fail!"),
                                     t_str);
            this->m_quickWidget->close();
        });
        SN_connectToLocalSocketFault();
    }

    //4-sql read finish: sql_mcRecorder->qml ui
    connect(sql_mcRecorder, &Sql_MCRecorder::sn_sqlAlarmWriteFinish,
            this, [this](QVector<QString> t_now, QVector<QString> t_history){
        QObject *pObj = (QObject *)m_quickWidget->rootObject();
        QString retVal;
        QMetaObject::invokeMethod(pObj , "qmlSL_sqlAlarmWriteFinishCallback",
                                  Q_ARG(QVariant, QVariant::fromValue(t_now)),
                                  Q_ARG(QVariant, QVariant::fromValue(t_history)));
    });

    //5-ExcRecordDisplayer
    m_excRecordDisplayer = new ExcRecordDisplayer(m_quickWidget);

//    std::cout << "father thread:" << std::this_thread::get_id() << std::endl;
}

void ExcQmlModbusInterface::run()
{
    m_localSocket = new QLocalSocket();
    m_localSocket->abort();
    sleep(5);
    m_localSocket->connectToServer(tr("EXCSCREEN"));
    if (!m_localSocket->waitForConnected(3000)) SN_close();
//    connect(m_localSocket, &QLocalSocket::error, this, [this](QLocalSocket::LocalSocketError socketError){SN_close();});
    connect(m_localSocket, &QLocalSocket::disconnected, this, [this](){SN_close();});
    connect(m_localSocket, &QLocalSocket::readyRead, this, [this](){
        QVector<quint16> t_vec;
        QByteArray t_byar = m_localSocket->readAll();
        if(t_byar.isEmpty())
        {
#ifdef _CPP_DEBUG_PRINT_
            qDebug() << "localsocket接收空数据";
#endif
        }
        else if((t_byar.at(2)|t_byar.at(3)<<8)!=t_byar.size()/2-2)
        {
#ifdef _CPP_DEBUG_PRINT_
            qDebug() << "localsocket接收多帧数据:"
                     << QString("0x%1,0x%2").arg(QString::number(((quint8)t_byar.at(2)|(quint8)t_byar.at(3)<<8),16)).arg(QString::number((quint16)(t_byar.size()/2-2),16))
                     << "数据起始地址:"
                     << QString("0x%1").arg(QString::number(((quint8)t_byar.at(0)|(quint8)t_byar.at(1)<<8),16));
#endif
            for(int i=0; i<t_byar.size()/2;)
            {
                int t_size = (t_byar.at(2+i*2)|t_byar.at(3+i*2))+2;
                if(t_byar.size()/2>=t_size+i)
                    for(int j=0; j<t_size; j++)
                        t_vec.push_back((quint16)((unsigned char)t_byar.at(2*j+i*2)|(unsigned char)t_byar.at(2*j+1+i*2)<<8));
                else break;
                sql_mcRecorder->cpp_modbusRecFinish(t_vec);
                i+=t_size;
                t_vec.clear();
            }
        }
        else{
            for(int i=0; i<t_byar.size()/2; i++)
                t_vec.push_back((quint16)((unsigned char)t_byar.at(2*i)|(unsigned char)t_byar.at(2*i+1)<<8));
            sql_mcRecorder->cpp_modbusRecFinish(t_vec);
        }
    });
    exec();
}
